package com.linq.cool.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linq.cool.api.domain.SysDept;
import com.linq.cool.api.domain.SysRole;
import com.linq.cool.api.domain.SysUser;
import com.linq.cool.common.constants.UserConstants;
import com.linq.cool.common.core.exception.BusinessException;
import com.linq.cool.common.core.utils.StringUtils;
import com.linq.cool.common.core.utils.TreeUtils;
import com.linq.cool.common.datascope.annotation.DataScope;
import com.linq.cool.system.mapper.SysDeptMapper;
import com.linq.cool.system.service.SysDeptService;
import com.linq.cool.system.service.SysUserService;
import com.linq.cool.system.vo.TreeSelectVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: yqlin
 * @Date: 2020/12/29 19:16
 * @Description:
 * @Version: 1.0.0
 */
@Service

public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {
    @Autowired
    private SysRoleServiceImpl sysRoleService;
    @Autowired
    private SysUserService sysUserService;


    @Override
    public List<TreeSelectVO> buildDeptTreeSelect(List<SysDept> depts) {
        return TreeUtils.toTreeList(depts, 0L, Long.class, SysDept.class).stream().map(TreeSelectVO::new).collect(Collectors.toList());
    }

    @Override
    public List<Long> listByRoleId(Long roleId) {
        SysRole role = sysRoleService.getRoleById(roleId);
        return baseMapper.listByRoleId(roleId, role.isDeptCheckStrictly());
    }

    @DataScope(deptAlias = "d")
    @Override
    public List<SysDept> listByParams(SysDept sysDept) {
        return baseMapper.listByParams(sysDept);
    }

    @Override
    public boolean checkNameUnique(SysDept dept) {
        Long deptId = StringUtils.isNull(dept.getId()) ? -1L : dept.getId();
        SysDept one = this.getOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getName, dept.getName())
                                          .eq(SysDept::getParentId, dept.getParentId()));
        return null != one && !deptId.equals(one.getId());
    }

    @Override
    public boolean saveDept(SysDept dept) {
        SysDept info = this.getById(dept.getParentId());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (!UserConstants.StateEnum.STATUS_NORMAL.getCode().equals(info.getStatus())) {
            throw new BusinessException("部门停用，不允许新增");
        }
        dept.setAncestorIds(info.getAncestorIds() + "," + dept.getParentId());
        return this.save(dept);
    }

    @Override
    public boolean checkNormalChild(Long deptId) {
        return baseMapper.countNormalChild(deptId) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateDept(SysDept dept) {
        // 新父节点
        SysDept newParentDept = getById(dept.getParentId());
        SysDept oldDept = getById(dept.getId());
        if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept)) {
            String newAncestors = newParentDept.getAncestorIds() + "," + newParentDept.getId();
            String oldAncestors = oldDept.getAncestorIds();
            dept.setAncestorIds(newAncestors);
            this.updateDeptChildren(dept.getId(), newAncestors, oldAncestors);
        }
        boolean flag = this.updateById(dept);
        if (UserConstants.StateEnum.STATUS_NORMAL.getCode().equals(dept.getStatus())) {
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            SysDept curDept = this.getById(dept.getId());
            baseMapper.updateParentStatus(curDept);
        }
        return flag;
    }

    @Override
    public boolean hasChild(Long deptId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<SysDept>()
                                              .eq(SysDept::getIsDeleted, UserConstants.StateEnum.STATUS_NORMAL.getCode())
                                              .eq(SysDept::getParentId, deptId)
        ) > 0;
    }

    @Override
    public boolean checkExistUser(Long deptId) {
        return sysUserService.count(new LambdaQueryWrapper<SysUser>()
                                            .eq(SysUser::getDeptId, deptId)
                                            .eq(SysUser::getIsDeleted, UserConstants.StateEnum.STATUS_NORMAL.getCode())
        ) > 0;
    }


    /**
     * 修改子元素关系
     *
     * @param deptId       被修改的部门ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    private void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
        List<SysDept> children = baseMapper.listChildrenById(deptId);
        for (SysDept child : children) {
            child.setAncestorIds(child.getAncestorIds().replace(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            baseMapper.updateChildren(children);
        }
    }
}

